package com.guo.mixframe.framework.utils

import com.guo.mixframe.framework.log.LogPrint
import io.vertx.core.http.HttpServerRequest

/**
 * @author  gx
 * @description
 */
object IPAddrHelper {
  /**
   * 获取请求IP
   */
  fun checkIp(request: HttpServerRequest): String {
    fun isValid(ipStr:String?):Boolean {
      return !(ipStr.isNullOrEmpty() || ipStr.equals("unKnown", true))
    }

    var ip: String?
    while(true) {
      ip = request.getHeader("CF-Connecting-IP")
      if (isValid(ip))
        break
      ip = request.getHeader("X-Real-IP")
      if (isValid(ip))
        break
      ip = request.getHeader("X-Forwarded-For")
      if (isValid(ip)) {
        ip = ip.split(',')[0]
        break
      }
      ip = request.getHeader("Proxy-Client-IP")
      if (isValid(ip))
        break
      ip = request.getHeader("WL-Proxy-Client-IP")
      if (isValid(ip))
        break
      ip = request.getHeader("HTTP_CLIENT_IP")
      if (isValid(ip))
        break
      ip = request.getHeader("HTTP_X_FORWARDED_FOR")
      if (isValid(ip))
        break
      ip = request.remoteAddress().host()
      break
    }
    return ip!!
  }

  /**
   * 判断ip是否为本机ip
   */
  fun isLocalHost(ip: String): Boolean {
    return "localhost" == ip || "127.0.0.1" == ip || "0:0:0:0:0:0:0:1" == ip
  }

  /**
   * 判断ipAddress是否为局域网ip
   */
  fun isInnerIP(ipAddress: String): Boolean {
    return isInnerIP(ipAddress, false)
  }

  /**
   * 判断ipAddress是否为局域网ip
   */
  fun isInnerIP(ipAddress: String, needPrint: Boolean): Boolean {
    if (ipAddress.contains(":")) {
      /* ipv6 先不判断 */
      return false
    }
    val ipNum = getIpNum(ipAddress)
    /*
     * 私有IP:
     * A类  10.0.0.0-10.255.255.255
     * B类  172.16.0.0-172.31.255.255
     * C类  192.168.0.0-192.168.255.255
     * 当然，还有127这个网段是环回地址
     */
    val aBegin = getIpNum("10.0.0.0")
    val aEnd = getIpNum("10.255.255.255")
    val bBegin = getIpNum("172.16.0.0")
    val bEnd = getIpNum("172.31.255.255")
    val cBegin = getIpNum("192.168.0.0")
    val cEnd = getIpNum("192.168.255.255")
    val isInnerIp = isInner(ipNum, aBegin, aEnd)
      || isInner(ipNum, bBegin, bEnd)
      || isInner(ipNum, cBegin, cEnd)
      || ipAddress == "127.0.0.1"
    if (needPrint) {
      val sb = StringBuilder()
      sb.append("ipAddress: ").append(ipAddress)
        .append(", aBegin: ").append(aBegin)
        .append(", aEnd: ").append(aEnd)
        .append(", bBegin: ").append(bBegin)
        .append(", bEnd: ").append(bEnd)
        .append(", cBegin: ").append(cBegin)
        .append(", cEnd: ").append(cEnd)
        .append(", isInnerIp: ").append(isInnerIp)
      LogPrint.logger.debug(sb.toString())
    }
    return isInnerIp
  }

  /**
   * 将ipAddress转换为long
   */
  private fun getIpNum(ipAddress: String): Long {
    val ip = StringHelper.toLongArray(ipAddress, "\\.")
    return (ip[0] shl 24) + (ip[1] shl 16) + (ip[2] shl 8) + ip[3]
  }

  /**
   * 判断userIp是否在begin和end之间
   */
  private fun isInner(userIp: Long, begin: Long, end: Long): Boolean {
    return userIp in begin..end
  }
}
